#include <iostream>
#include <pthread.h>
#include <functional>

using namespace std;

void printFirst()
{
    cout << "first";
}

void printSecond()
{

    cout << "second";
}

void printThird()
{
    cout << "third" << endl;
}

class Foo
{
public:
    Foo()
    {
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond2, nullptr);
        pthread_cond_init(&_cond3, nullptr);
    }
    ~Foo()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond2);
        pthread_cond_destroy(&_cond3);
    }

    void first(function<void()> printFirst)
    {

        // printFirst() outputs "first". Do not change or remove this line.
        printFirst();
    }

    void second(function<void()> printSecond)
    {

        // printSecond() outputs "second". Do not change or remove this line.
        printSecond();
    }

    void third(function<void()> printThird)
    {

        // printThird() outputs "third". Do not change or remove this line.
        printThird();
    }

public:
    bool _1called = false;
    bool _2called = false;
    pthread_mutex_t _mutex;
    pthread_cond_t _cond2;
    pthread_cond_t _cond3;
};

Foo foo;

void *threadRoutine(void *args)
{
    int64_t n = (int64_t)args;

    pthread_mutex_lock(&foo._mutex);

    if (n == 1)
    {
        foo.first(printFirst);
        foo._1called = true;
        pthread_cond_signal(&foo._cond2);
    }

    else if (n == 2)
    {
        // 如果1还没执行
        if (!foo._1called)
        {
            pthread_cond_wait(&foo._cond2, &foo._mutex);
        }

        foo.second(printSecond);
        foo._2called = true;
        pthread_cond_signal(&foo._cond3);
    }

    else if (n == 3)
    {
        // 如果2还没执行(2没被执行，1肯定也没被执行)
        if (!foo._2called)
        {
            pthread_cond_wait(&foo._cond3, &foo._mutex);
        }

        foo.third(printThird);
    }

    pthread_mutex_unlock(&foo._mutex);

    return nullptr;
}

int main()
{
    int64_t num[3] = {0};
    for (int i = 0; i < 3; i++)
        cin >> num[i];

    pthread_t ta, tb, tc;
    pthread_create(&ta, nullptr, threadRoutine, (void *)num[0]);
    pthread_create(&tb, nullptr, threadRoutine, (void *)num[1]);
    pthread_create(&tc, nullptr, threadRoutine, (void *)num[2]);


    pthread_join(ta, nullptr);
    pthread_join(tb, nullptr);
    pthread_join(tc, nullptr);

    return 0;
}